package com.ruoyi.web.service.warning.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.domain.device.DeviceInfo;
import com.ruoyi.web.domain.warning.WarningFactorRecord;
import com.ruoyi.web.domain.warning.WarningInsectRecord;
import com.ruoyi.web.enums.DeviceTypeEnum;
import com.ruoyi.web.enums.InsectWarningTypeEnum;
import com.ruoyi.web.mapper.warning.WarningInsectRecordMapper;
import com.ruoyi.web.pojo.request.warning.WarningInsectRecordRequest;
import com.ruoyi.web.pojo.request.warning.WarningRecordCountByDayRequest;
import com.ruoyi.web.pojo.vo.warning.HomeWarningListVo;
import com.ruoyi.web.pojo.vo.warning.HomeWarningStatisticsVo;
import com.ruoyi.web.pojo.vo.warning.WarningRecordCountByDayVO;
import com.ruoyi.web.pojo.vo.warning.WarningRecordCountVO;
import com.ruoyi.web.service.device.DeviceInfoService;
import com.ruoyi.web.service.warning.WarningFactorRecordService;
import com.ruoyi.web.service.warning.WarningInsectRecordService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 虫情预警记录 服务实现类
 * @author fwx
 * @date 2024-02-06 14:32:38
 */
@Service
public class WarningInsectRecordServiceImpl extends ServiceImpl<WarningInsectRecordMapper, WarningInsectRecord> implements WarningInsectRecordService {

    @Autowired
    private WarningFactorRecordService warningFactorRecordService;

    @Autowired
    private DeviceInfoService deviceInfoService;


    /**
    * 新增虫情预警记录
    */
    @Override
    public void insert(WarningInsectRecord WarningInsectRecord){
        super.save(WarningInsectRecord);
    }

    @Override
    public void insertList(List<WarningInsectRecord> records){
        if(CollectionUtils.isEmpty(records)){
            return;
        }
        super.saveBatch(records);
    }

    /**
    * 修改虫情预警记录
    */
    @Override
    public void update(WarningInsectRecord WarningInsectRecord){
        super.updateById(WarningInsectRecord);
    }

    /**
    * 删除虫情预警记录
    */
    @Override
    public void delete(String id){
        super.removeById(id);
    }

    /**
    *  分页查询虫情预警记录
    */
    @Override
    public void queryPage(IPage<WarningInsectRecord> page){
        QueryWrapper<WarningInsectRecord> query  = new QueryWrapper<>();
        super.page(page,query);
    }

    @Override
    public List<WarningInsectRecord> queryPage(WarningInsectRecordRequest request){
        QueryWrapper<WarningInsectRecord> query  = new QueryWrapper<>();

        if(request.getUserId() != null){
            List<DeviceInfo> infos = deviceInfoService.getByUser();
            if(infos.size() == 0){
                return new ArrayList<>();
            }
            query.lambda().in(WarningInsectRecord::getDeviceId,infos.stream().map(DeviceInfo::getDeviceId).collect(Collectors.toList()));
        }

        request.bulidWrapper(query);

        PageUtils.startPage();
        List<WarningInsectRecord> list = super.list(query);
        return list;
    }

    @Override
    public List<WarningInsectRecord> getByType(Integer warningType){
        QueryWrapper<WarningInsectRecord> query  = new QueryWrapper<>();
        query.lambda().eq(WarningInsectRecord::getInsectWarningType,warningType)
                .ge(WarningInsectRecord::getWarningTime,DateUtils.getYearBeginDate())
        ;

        List<WarningInsectRecord> list = super.list(query);
        return list;
    }

    @Override
    public List<WarningInsectRecord> getByUserType(Integer warningType){
        List<String> ids = deviceInfoService.getIdsByUser(DeviceTypeEnum.FL2.getValue());

        QueryWrapper<WarningInsectRecord> query  = new QueryWrapper<>();
        query.lambda().eq(WarningInsectRecord::getInsectWarningType,warningType)
                .in(WarningInsectRecord::getDeviceId,ids)
                .ge(WarningInsectRecord::getWarningTime,DateUtils.getYearBeginDate())
        ;

        List<WarningInsectRecord> list = super.list(query);
        return list;
    }

    @Override
    public Long countByDay(String start, String end){
        QueryWrapper<WarningInsectRecord> query  = new QueryWrapper<>();
        query.lambda().between(WarningInsectRecord::getWarningTime,start,end);
        Long count = super.count(query);
        return count;
    }

    @Override
    public List<WarningInsectRecord> getListByDay(String start, String end){
        QueryWrapper<WarningInsectRecord> query  = new QueryWrapper<>();
        query.lambda().between(WarningInsectRecord::getWarningTime,start,end);
        List<WarningInsectRecord> list = super.list(query);
        return list;
    }

    @Override
    public WarningRecordCountVO getInsectRecordCount(){

        WarningRecordCountVO result = new WarningRecordCountVO();

        Long all = super.count();
        Long month = this.countByDay(DateUtils.getMonthBeginDate(), DateUtils.getTomorrowStr());
        Long day = this.countByDay(DateUtils.getNowStr(), DateUtils.getTomorrowStr());

        result.setAllCount(all);
        result.setMonthCount(month);
        result.setDayCount(day);
        return result;
    }

    @Override
    public List<WarningRecordCountByDayVO> getInsectRecordCountByDay(WarningRecordCountByDayRequest request){
        List<WarningInsectRecord> list = this.getListByDay(request.getStartTime(), request.getEndTime());

        List<WarningRecordCountByDayVO> result = new ArrayList<>();

        if(CollectionUtils.isEmpty(list)){
            return result;
        }

        Map<String, List<WarningInsectRecord>> recMap
                = list.stream().collect(Collectors.groupingBy(rec -> DateUtils.formatDate(rec.getWarningTime())));

        for (String date : recMap.keySet()) {
            WarningRecordCountByDayVO vo = new WarningRecordCountByDayVO();
            vo.setDateStr(date);
            vo.setWarningNum(recMap.get(date).size());
            vo.setInsectRecords(recMap.get(date));
            result.add(vo);
        }

        return result;
    }

    @Override
    public WarningRecordCountVO getRecordCount(){
        WarningRecordCountVO factorRecordCount = warningFactorRecordService.getFactorRecordCount();
        WarningRecordCountVO insectRecordCount = this.getInsectRecordCount();
        insectRecordCount.addCount(factorRecordCount);
        return insectRecordCount;
    }

    @Override
    public List<WarningRecordCountByDayVO> getRecordCountByDay(WarningRecordCountByDayRequest request){

        List<WarningRecordCountByDayVO> factorList = warningFactorRecordService.getFactorRecordCountByDay(request);

        List<WarningRecordCountByDayVO> insectList = this.getInsectRecordCountByDay(request);
        List<WarningRecordCountByDayVO> result = WarningRecordCountByDayVO.addCountList(factorList, insectList);

        return result;
    }

    /**
     * @desc  首页-获取右下角的预警统计
     * @author fwx 2024/2/18 14:12
     **/
    @Override
    public HomeWarningStatisticsVo getHomeWarningStatistics(Integer dateType){

        HomeWarningStatisticsVo homeWarningStatisticsVo = new HomeWarningStatisticsVo();

        String dataFormat = "yyyy-MM-dd HH:mm:ss";

        String startTime = "";
        String endTime = "";
        String lastStartTime = "";
        String lastEndTime = "";
        switch (dateType) {
            case 1:
                startTime = DateUtil.beginOfWeek(new Date()).toString(dataFormat);
                endTime = DateUtil.endOfWeek(new Date()).toString(dataFormat);
                lastStartTime = DateUtil.beginOfWeek(DateUtil.lastWeek()).toString(dataFormat);
                lastEndTime = DateUtil.endOfWeek(DateUtil.lastWeek()).toString(dataFormat);
                break;
            case 2:
                startTime = DateUtil.beginOfMonth(new Date()).toString(dataFormat);
                endTime = DateUtil.endOfMonth(new Date()).toString(dataFormat);
                lastStartTime = DateUtil.beginOfMonth(DateUtil.lastMonth()).toString(dataFormat);
                lastEndTime = DateUtil.endOfMonth(DateUtil.lastMonth()).toString(dataFormat);
                break;
            case 3:
                startTime = DateUtil.beginOfYear(new Date()).toString(dataFormat);
                endTime = DateUtil.endOfYear(new Date()).toString(dataFormat);
                lastStartTime = DateUtil.beginOfYear(DateUtil.offset(new Date(), DateField.YEAR,-1)).toString(dataFormat);
                lastEndTime = DateUtil.endOfYear(DateUtil.offset(new Date(),DateField.YEAR,-1)).toString(dataFormat);
                break;
            default:
                throw new RuntimeException("时间类型异常，只能是 1周 2月 3年");
        }

        Long insectCount = 0L; //本次昆虫数据
        Long factorCount = 0L; //本次灾情数量
        Long lastInsectCount = 0L; //上次昆虫数据
        Long lastFactorCount = 0L; //上次灾情数量

        List<HomeWarningListVo> records = new ArrayList<>(); //最新的十条

        //获取虫情预警汇总数据
        List<DeviceInfo> insectDeviceType = deviceInfoService.getByUser(DeviceTypeEnum.FL2.getValue());
        if(StringUtils.isNotEmpty(insectDeviceType)) {
            List<String> insectIdList = insectDeviceType.stream().map(DeviceInfo::getDeviceId).collect(Collectors.toList());
            insectCount = this.baseMapper.selectCount(new LambdaQueryWrapper<WarningInsectRecord>()
                    .in(WarningInsectRecord::getDeviceId,insectIdList)
                    .ge(WarningInsectRecord::getWarningTime,startTime)
                    .le(WarningInsectRecord::getWarningTime,endTime));
            lastInsectCount = this.baseMapper.selectCount(new LambdaQueryWrapper<WarningInsectRecord>()
                    .in(WarningInsectRecord::getDeviceId,insectIdList)
                    .ge(WarningInsectRecord::getWarningTime,lastStartTime)
                    .le(WarningInsectRecord::getWarningTime,lastEndTime));
            List<WarningInsectRecord> insectRecords = this.baseMapper.selectList(new LambdaQueryWrapper<WarningInsectRecord>()
                    .in(WarningInsectRecord::getDeviceId,insectIdList)
                    .ge(WarningInsectRecord::getWarningTime,startTime)
                    .le(WarningInsectRecord::getWarningTime,endTime)
                    .orderByDesc(WarningInsectRecord::getWarningTime)
                    .last(" limit 10"));
            if(StringUtils.isNotEmpty(insectRecords)) {
                for (WarningInsectRecord s : insectRecords) {
                    HomeWarningListVo homeWarningListVo = new HomeWarningListVo();
                    BeanUtils.copyProperties(s,homeWarningListVo);
                    homeWarningListVo.setInsectName(s.getInsectName()+" "+s.getWarningValue() + "个");
                    //homeWarningListVo.setUnitName("个");
                    homeWarningListVo.setWarningValue(null);
                    homeWarningListVo.setDeviceName(InsectWarningTypeEnum.getByCode(s.getInsectWarningType()).getDescription());
                    int send = s.getIsSendSms() == null ? 0 : s.getIsSendSms();
                    int click = s.getIsSendEmail() == null ? 0 : s.getIsSendEmail();
                    if(send == 1 && click == 0) {
                        homeWarningListVo.setIsSend(1);
                    }
                    if(send == 0 && click == 1) {
                        homeWarningListVo.setIsSend(2);
                    }
                    if(send == 1 && click == 1) {
                        homeWarningListVo.setIsSend(3);
                    }
                    records.add(homeWarningListVo);
                }
            }
        }
        //获取灾情汇总数据
        List<DeviceInfo> factorDeviceType = deviceInfoService.getByUser(DeviceTypeEnum.FL5.getValue());
        if(StringUtils.isNotEmpty(factorDeviceType)) {
            List<String> faIdList = factorDeviceType.stream().map(DeviceInfo::getDeviceId).collect(Collectors.toList());
            factorCount = warningFactorRecordService.count(new LambdaQueryWrapper<WarningFactorRecord>()
                    .in(WarningFactorRecord::getDeviceId,faIdList)
                    .ge(WarningFactorRecord::getWarningTime,startTime)
                    .le(WarningFactorRecord::getWarningTime,endTime));
            lastFactorCount = warningFactorRecordService.count(new LambdaQueryWrapper<WarningFactorRecord>()
                    .in(WarningFactorRecord::getDeviceId,faIdList)
                    .ge(WarningFactorRecord::getWarningTime,lastStartTime)
                    .le(WarningFactorRecord::getWarningTime,lastEndTime));
            List<WarningFactorRecord> factorRecords = warningFactorRecordService.list(new LambdaQueryWrapper<WarningFactorRecord>()
                    .in(WarningFactorRecord::getDeviceId,faIdList)
                    .ge(WarningFactorRecord::getWarningTime,startTime)
                    .le(WarningFactorRecord::getWarningTime,endTime)
                    .orderByDesc(WarningFactorRecord::getWarningTime)
                    .last(" limit 10"));
            if(StringUtils.isNotEmpty(factorRecords)) {
                for (WarningFactorRecord s : factorRecords) {
                    HomeWarningListVo homeWarningListVo = new HomeWarningListVo();
                    BeanUtils.copyProperties(s,homeWarningListVo);
                    //homeWarningListVo.setWarningValue(Integer.parseInt(s.getAbnormalValue()));
                    homeWarningListVo.setInsectName(s.getAbnormalValue());
                    homeWarningListVo.setDescription(s.getWarningRecommend());
                    //homeWarningListVo.setUnitName(s.getFactorUnit());
                    homeWarningListVo.setDeviceName(s.getWarningName());
                    int send = s.getIsSendSms() == null ? 0 : s.getIsSendSms();
                    int click = s.getIsSendEmail() == null ? 0 : s.getIsSendEmail();
                    if(send == 1 && click == 0) {
                        homeWarningListVo.setIsSend(1);
                    }
                    if(send == 0 && click == 1) {
                        homeWarningListVo.setIsSend(2);
                    }
                    if(send == 1 && click == 1) {
                        homeWarningListVo.setIsSend(3);
                    }
                    records.add(homeWarningListVo);
                }
            }
        }

        //获取最新的十条数据（虫情，灾情一起）
        if(StringUtils.isNotEmpty(records)) {
            Collections.sort(records,Comparator.comparing(HomeWarningListVo::getWarningTime).reversed());
            if(records.size() > 10) {
                records = records.subList(0,10);
            }
        }
        //出来返回参数
        homeWarningStatisticsVo.setRecords(records);
        homeWarningStatisticsVo.setAllCount(insectCount + factorCount);
        homeWarningStatisticsVo.setInsectCount(insectCount);
        homeWarningStatisticsVo.setFactorCount(factorCount);
        //处理环比
        long total = insectCount + factorCount;
        long lastTotal = lastInsectCount + lastFactorCount;
        long sub = total - lastTotal;
        if(sub < 0) {
            homeWarningStatisticsVo.setChangeType(1);
            homeWarningStatisticsVo.setChangeDescription("绿色防控初见成效");
        }else {
            homeWarningStatisticsVo.setChangeDescription("需注意及时防控");
        }
        if(lastTotal == 0) {
            if(total != 0) {
                homeWarningStatisticsVo.setChangeNum(BigDecimal.valueOf(100));
            }
        }else {
            if(total == 0) {
                homeWarningStatisticsVo.setChangeNum(BigDecimal.valueOf(100));
            }else {
                BigDecimal bigDecimal = BigDecimal.valueOf(sub).divide(BigDecimal.valueOf(lastTotal),2,BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)).abs();
                homeWarningStatisticsVo.setChangeNum(bigDecimal);
            }
        }

        return homeWarningStatisticsVo;

    }

    /**
    * 查询所有虫情预警记录
    */
    @Override
    public List<WarningInsectRecord> queryAll(){
        QueryWrapper<WarningInsectRecord> query  = new QueryWrapper<>();
        List<WarningInsectRecord> list = super.list(query);
        return list;
    }

    /**
    * 根据id查询虫情预警记录
    */
    @Override
    public WarningInsectRecord findById(String id){
        WarningInsectRecord res = super.getById(id);
        return res;
    }

}
